package com.newsnetwork.user.service.impl;

import com.newsnetwork.enums.Sex;
import com.newsnetwork.enums.UserStatus;
import com.newsnetwork.exception.GraceException;
import com.newsnetwork.grace.result.ResponseStatusEnum;
import com.newsnetwork.pojo.AppUser;
import com.newsnetwork.pojo.bo.UpdateUserInfoBO;
import com.newsnetwork.user.mapper.AppUserMapper;
import com.newsnetwork.user.service.UserService;
import com.newsnetwork.utils.DesensitizationUtil;
import com.newsnetwork.utils.JsonUtils;
import com.newsnetwork.utils.RedisOperator;
import org.n3r.idworker.Sid;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;

/**
 * @author: HuangDekai
 * @date: 2022/11/4 17:15
 * @version: 1.0
 * @since: jdk8
 * @description: 与用户相关的 Service 的实现类, 查询用户是否存在, 添加用户等
 */

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private AppUserMapper appUserMapper;

    @Autowired
    public RedisOperator redisOperator;
    public static final String REDIS_USER_INFO = "redis_user_info";

    /**
     * Sid - 雪花算法获得唯一id
     * 如果要考虑数据库分库分表, 数据库表 主键id 必须保证全局(全库)唯一, 不得重复
     * sid.nextShort()
     */
    @Autowired
    private Sid sid;

    /**
     * 设置默认头像的地址
     */
    private final String defaultFace = "https://newsnetwork.oss-cn-hangzhou.aliyuncs.com/images/default.png";

    /**
     * 查询用户是否存在, 存在返回用户信息
     *
     * @param mobile 手机号
     * @return 用户信息
     */
    @Override
    public AppUser queryMobileIsExist(String mobile) {
        Example userExample = new Example(AppUser.class);
        Example.Criteria userCriteria = userExample.createCriteria();
        userCriteria.andEqualTo("mobile", mobile);
        AppUser appUser = appUserMapper.selectOneByExample(userExample);
        return appUser;
    }

    /**
     * 创建用户, 新增用户记录到数据库
     *
     * @param mobile 手机号
     * @return 用户信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AppUser createUser(String mobile) {

        String userId = sid.nextShort();
        AppUser user = new AppUser();

        user.setId(userId);
        user.setMobile(mobile);
        user.setNickname("用户:" + DesensitizationUtil.commonDisplay(mobile));
        user.setFace(defaultFace);
        user.setBirthday(new Date());
        user.setSex(Sex.secret.type);
        user.setActiveStatus(UserStatus.INACTIVE.type);

        user.setTotalIncome(0);
        user.setCreatedTime(new Date());
        user.setUpdatedTime(new Date());

        appUserMapper.insert(user);

        return user;
    }

    /**
     * 根据用户主键消息查询Id
     * @param userId 用户Id
     * @return
     */
    @Override
    public AppUser getUser(String userId) {
        return appUserMapper.selectByPrimaryKey(userId);
    }

    /**
     * 用户修改信息，完善资料，并且激活
     * @param updateUserInfoBO 用户信息
     */
    @Override
    public void updateUserInfo(UpdateUserInfoBO updateUserInfoBO) {

        String userId = updateUserInfoBO.getId();

        // 保证双写一致，先删除redis中的数据，后更新数据库
        redisOperator.del(REDIS_USER_INFO+":"+userId);

        AppUser appUser = new AppUser();
        BeanUtils.copyProperties(updateUserInfoBO, appUser);

        appUser.setUpdatedTime(new Date());
        appUser.setActiveStatus(UserStatus.ACTIVE.type);

        int result = appUserMapper.updateByPrimaryKeySelective(appUser);

        // 更新失败
        if (result != 1) {
            GraceException.display(ResponseStatusEnum.USER_UPDATE_ERROR);
        }

        AppUser user = getUser(userId);
        redisOperator.set(REDIS_USER_INFO+":"+userId, JsonUtils.objectToJson(user));

        try {
            Thread.sleep(100);
            redisOperator.del(REDIS_USER_INFO+":"+userId);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
